From 928c98a84efd2c72bc3ff9fe139ad5296091110a Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Wed, 29 Nov 2017 08:13:06 +0100 Subject: [PATCH] gdk: Add serializers and deserializers for GFile in particular, support: GFile <=> text/uri-list GFile => text/plain --- gdk/gdkcontentdeserializer.c | 69 +++++++++++++++++++++++++++++++++++ gdk/gdkcontentserializer.c | 71 ++++++++++++++++++++++++++++++++++++ tests/testclipboard2.c | 8 ++++ 3 files changed, 148 insertions(+) diff --git a/gdk/gdkcontentdeserializer.c b/gdk/gdkcontentdeserializer.c index f6a3f6f2bf..b9a369f2ab 100644 --- a/gdk/gdkcontentdeserializer.c +++ b/gdk/gdkcontentdeserializer.c @@ -22,6 +22,7 @@ #include "gdkcontentdeserializer.h" #include "gdkcontentformats.h" +#include "gdkintl.h" #include @@ -523,6 +524,68 @@ string_deserializer (GdkContentDeserializer *deserializer) g_object_unref (filter); } +static void +file_uri_deserializer_finish (GObject *source, + GAsyncResult *result, + gpointer deserializer) +{ + GOutputStream *stream = G_OUTPUT_STREAM (source); + GError *error = NULL; + gssize written; + char *str; + char **uris; + + written = g_output_stream_splice_finish (stream, result, &error); + if (written < 0) + { + gdk_content_deserializer_return_error (deserializer, error); + return; + } + + /* write terminating NULL */ + if (!g_output_stream_write (stream, "", 1, NULL, &error)) + { + gdk_content_deserializer_return_error (deserializer, error); + return; + } + + str = g_memory_output_stream_steal_data (G_MEMORY_OUTPUT_STREAM ( + g_filter_output_stream_get_base_stream (G_FILTER_OUTPUT_STREAM (stream)))); + uris = g_uri_list_extract_uris (str); + g_free (str); + + if (uris == NULL || uris[0] == NULL) + { + error = g_error_new (G_IO_ERROR, G_IO_ERROR, _("No file given")); + gdk_content_deserializer_return_error (deserializer, error); + } + else + { + GFile *file = g_file_new_for_uri (uris[0]); + + g_value_take_object (gdk_content_deserializer_get_value (deserializer), file); + gdk_content_deserializer_return_success (deserializer); + } + g_strfreev (uris); +} + +static void +file_uri_deserializer (GdkContentDeserializer *deserializer) +{ + GOutputStream *output; + + output = g_memory_output_stream_new_resizable (); + + g_output_stream_splice_async (output, + gdk_content_deserializer_get_input_stream (deserializer), + G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE | G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET, + gdk_content_deserializer_get_priority (deserializer), + gdk_content_deserializer_get_cancellable (deserializer), + file_uri_deserializer_finish, + deserializer); + g_object_unref (output); +} + static void init (void) { @@ -576,6 +639,12 @@ init (void) g_slist_free (formats); + gdk_content_register_deserializer ("text/uri-list", + G_TYPE_FILE, + file_uri_deserializer, + NULL, + NULL); + gdk_content_register_deserializer ("text/plain;charset=utf-8", G_TYPE_STRING, string_deserializer, diff --git a/gdk/gdkcontentserializer.c b/gdk/gdkcontentserializer.c index 045cd20ce9..eddc8be64e 100644 --- a/gdk/gdkcontentserializer.c +++ b/gdk/gdkcontentserializer.c @@ -511,6 +511,66 @@ string_serializer (GdkContentSerializer *serializer) g_object_unref (filter); } +static void +file_serializer_finish (GObject *source, + GAsyncResult *result, + gpointer serializer) +{ + GOutputStream *stream = G_OUTPUT_STREAM (source); + GError *error = NULL; + + if (!g_output_stream_write_all_finish (stream, result, NULL, &error)) + gdk_content_serializer_return_error (serializer, error); + else + gdk_content_serializer_return_success (serializer); +} + +static void +file_uri_serializer (GdkContentSerializer *serializer) +{ + GFile *file; + GString *str; + char *uri; + + str = g_string_new (NULL); + + file = g_value_get_object (gdk_content_serializer_get_value (serializer)); + uri = g_file_get_uri (file); + g_string_append (str, uri); + g_free (uri); + g_string_append (str, "\r\n"); + + g_output_stream_write_all_async (gdk_content_serializer_get_output_stream (serializer), + str->str, + str->len, + gdk_content_serializer_get_priority (serializer), + gdk_content_serializer_get_cancellable (serializer), + file_serializer_finish, + serializer); + gdk_content_serializer_set_task_data (serializer, g_string_free (str, FALSE), g_free); +} + +static void +file_text_serializer (GdkContentSerializer *serializer) +{ + GFile *file; + char *path; + + file = g_value_get_object (gdk_content_serializer_get_value (serializer)); + path = g_file_get_path (file); + if (path == NULL) + path = g_file_get_uri (file); + + g_output_stream_write_all_async (gdk_content_serializer_get_output_stream (serializer), + path, + strlen (path), + gdk_content_serializer_get_priority (serializer), + gdk_content_serializer_get_cancellable (serializer), + file_serializer_finish, + serializer); + gdk_content_serializer_set_task_data (serializer, path, g_free); +} + static void init (void) { @@ -567,6 +627,17 @@ init (void) g_slist_free (formats); + gdk_content_register_serializer (G_TYPE_FILE, + "text/uri-list", + file_uri_serializer, + NULL, + NULL); + gdk_content_register_serializer (G_TYPE_FILE, + "text/plain;charset=utf-8", + file_text_serializer, + NULL, + NULL); + gdk_content_register_serializer (G_TYPE_STRING, "text/plain;charset=utf-8", string_serializer, diff --git a/tests/testclipboard2.c b/tests/testclipboard2.c index ccdc78a796..4baabf5f86 100644 --- a/tests/testclipboard2.c +++ b/tests/testclipboard2.c @@ -263,6 +263,14 @@ get_button_list (GdkClipboard *clipboard, clipboard, "Invalid UTF-8"); + g_value_init (&value, G_TYPE_FILE); + g_value_take_object (&value, g_file_new_for_path (g_get_home_dir ())); + add_provider_button (box, + gdk_content_provider_new_for_value (&value), + clipboard, + "home directory"); + g_value_unset (&value); + return box; } -- 2.30.2